#include "stdafx.h"

extern WSASetLastError_proxy_t pTrueWSASetLastError;

int recv_proxy ( 
    __in  SOCKET s,
    __out char*  buf,
    __in  int    len,
    __in  int    flags
    )
{
    try
    {
    //SEND
        Header header(GetCurrentThreadId(), "recv");
        recv_in_inout recvIN(s, len, flags);
        
        std::vector<char> out_buffer;
        Serialize(header, recvIN, out_buffer);

        SendToClient (out_buffer);
        
    //RECEIVE()
        recv_out_inout recvOUT;

        std::vector<char> in_buffer;
        
        RecvFromClient (in_buffer, header);
        Deserialize deserialize(in_buffer);
        deserialize(recvOUT);

        if(recvOUT.wsa_last_error_ != 0)
        {
            pTrueWSASetLastError(recvOUT.wsa_last_error_);
            return SOCKET_ERROR;
        }
        if (recvOUT.ret_ > 0)
        {
            memcpy(buf, recvOUT.buf_, recvOUT.ret_);
        }
        return recvOUT.ret_;
    }
    catch (std::exception& ex)
    {
        LOG(plog::error) << "recv: " << ex.what();
    }
    pTrueWSASetLastError (WSAEWOULDBLOCK);
    return SOCKET_ERROR;
}

int recvfrom_proxy ( 
    __in  SOCKET s,
    __out char*  buf,
    __in  int    len,
    __in  int    flags,
    __out       struct sockaddr* from,
    __inout_opt int*             fromlen
    )
{
    try
    {
    //SEND
        Header header(GetCurrentThreadId(), "recvfrom");
        recvfrom_in_inout recvfromIN(s, len, flags, fromlen);
        
        std::vector<char> out_buffer;
        Serialize(header, recvfromIN, out_buffer);

        SendToClient (out_buffer);
        
    //RECEIVE()
        recvfrom_out_inout recvfromOUT;

        std::vector<char> in_buffer;
        
        RecvFromClient (in_buffer, header);
        Deserialize deserialize(in_buffer);
        deserialize(recvfromOUT);

        if(recvfromOUT.wsa_last_error_ != 0)
        {
            pTrueWSASetLastError(recvfromOUT.wsa_last_error_);
            return SOCKET_ERROR;
        }
        
        if (recvfromOUT.ret_ > 0)
        {
            memcpy(buf, recvfromOUT.buf_, recvfromOUT.ret_);
        }
        if (fromlen)
        {
            *fromlen = *recvfromOUT.fromlen_;
        }
        if (from)
        {
            memcpy (from, recvfromOUT.from_, *fromlen);
        }
        return recvfromOUT.ret_;
    }
    catch (std::exception& ex)
    {
        LOG(plog::error) << "recvfrom: " << ex.what();
    }
    pTrueWSASetLastError (WSAEWOULDBLOCK);
    return SOCKET_ERROR;
}
